
#ifndef __REAL3_H__
#define __REAL3_H__

#include "FileStream.h"
#include <d3dx9math.h>

class Real3
{
public:

	// Constructor
	Real3();
	Real3(float _x, float _y, float _z);

	// Sets the values
	void Set(float _x, float _y, float _z);

	// Operators
	bool friend operator == (const Real3 &a, const Real3 &b);
	bool friend operator != (const Real3 &a, const Real3 &b)
	{ return !(a == b); }
	Real3 friend operator + (const Real3 &a, const Real3 &b)
	{ return Real3(a.x + b.x, a.y + b.y, a.z + b.z); }
	Real3 friend operator - (const Real3 &a, const Real3 &b)
	{ return Real3(a.x - b.x, a.y - b.y, a.z - b.z); }
	Real3 friend operator * (const Real3 &a, float b)
	{ return Real3(a.x * b, a.y * b, a.z * b); }
	Real3 friend operator * (float b, const Real3 &a)
	{ return Real3(a.x * b, a.y * b, a.z * b); }

	Real3 operator += (const Real3 &a)
	{ x += a.x; y += a.y; z += a.z; return *this; }
	Real3 operator -= (const Real3 &a)
	{ x -= a.x; y -= a.y; z -= a.z; return *this; }
	Real3 operator *= (float a)
	{ x *= a; y *= a; z *= a; return *this; }

	// Write to a file
	void Write(FileStream &file)
	{
		if(file.IsBinary()) file.Write(((char*)&x), sizeof(Real3));
		else file.oFile << "(" << x << ", " << y << ", " << z << ")\n";
	}

	// Reads from file
	void Read(FileStream &file)
	{
		if(file.IsBinary()) file.Read(((char*)&x), sizeof(Real3));
		//else file << "(" << x << ", " << y << ", " << z << ")\n";
	}

	// Rotates the real3 (vector) around another real3 (vector), angle theta (radians)
	void Rotate(const Real3 &axis, float theta);

	// True if the given value is largest
	bool DominateX() { return x > y && x > z; }
	bool DominateY() { return y > z && y > x; }
	bool DominateZ() { return z > y && z > x; }

	// Reals
	float x;
	float y;
	float z;

	// Length methods
	float Length() const;
	float LengthSq() const;

	// Normalization Methods
	bool IsNormalized() const;
	void Normalize();

	// Is Zero
	bool IsZero() const;
};

// Vector Multiplication
Real3 Cross(const Real3 &a, const Real3 &b);
float Dot(const Real3 &a, const Real3 &b);

// Abs of a Real3
Real3 Abs(const Real3 &a);

// Length Methods
float LengthOf(const Real3 &a);
float LengthSqOf(const Real3 &a);

// Normal Of
Real3 NormalOf(Real3 a);

// Distance Between
float DistanceBetween(const Real3 &a, const Real3 &b);
float DistanceBetweenSq(const Real3 &a, const Real3 &b);

// Conversion to Matrix
D3DXMATRIX Real3ToRotMatrix(const Real3 &rot);

typedef Real3 Vector3;
typedef Real3 Euler3;

#endif // __REAL3_H__